package zhongbo.java.websocket.demo.service.impl;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Service;
import zhongbo.java.websocket.demo.dto.TopMessageDto;
import zhongbo.java.websocket.demo.model.User;
import zhongbo.java.websocket.demo.service.IMessageRankService;
import zhongbo.java.websocket.demo.service.IUserService;

import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * 说明：
 *
 * @author 钟波dellNotebook
 * @since 2025年03月24日 星期一 03:39:29
 */
@Service
@Slf4j
public class MessageRankServiceImpl implements IMessageRankService {

    private static final String MESSAGE_RANK_KEY = "chat:message_rank";

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Autowired
    private IUserService userService;

    @Override
    public void incrementMessageCount(String userId) {
        // incrementScore: 增加有序集合中某个成员的分数。如果成员不存在，则将其添加到有序集合中。
        redisTemplate.opsForZSet().incrementScore(MESSAGE_RANK_KEY, userId, 1);
    }

    @Override
    public List<TopMessageDto> getTopUserMessage() {
        List<TopMessageDto> result = new ArrayList<>();
        // reverseRangeWithScores: 获取有序集合中指定范围内的成员及其分数，并且是按照分数从高到低的顺序返回（即反向排序）。
        Set<ZSetOperations.TypedTuple<String>> topUserMessage = redisTemplate.opsForZSet().reverseRangeWithScores(MESSAGE_RANK_KEY, 0, 9);
        if (topUserMessage == null) {
            return null;
        }
        // 填充用户名
        List<String> userIds = new ArrayList<>();
        for (ZSetOperations.TypedTuple<String> topUser : topUserMessage) {
            String userId = topUser.getValue();
            userIds.add(userId);
        }
        // 根据ids查询用户列表
        List<User> userList = userService.listByIds(userIds);
        Map<String, User> userMap = new HashMap<>();
        for (User user : userList) {
            userMap.put(user.getId(), user);
        }
        // 组装用户名
        for (ZSetOperations.TypedTuple<String> topUser : topUserMessage) {
            Double score = topUser.getScore();
            String userId = topUser.getValue();
            User user = userMap.get(userId);
            String name = user.getName();
            TopMessageDto topMessageDto = new TopMessageDto(score, userId, name);
            result.add(topMessageDto);

        }
        return result;
    }

    // 限流检查
    @Override
    public boolean checkRateLimit(String userId) {
        String key = "chat:rate_limit:" + userId;
        Long count = redisTemplate.opsForValue().increment(key);
        redisTemplate.expire(key, 1, TimeUnit.MINUTES);
        return count != null && count <= 10; // 每分钟10条
    }
}
